 ///
 /// @file    TextQuery.cc
 /// @author  lemon(haohb13@gmail.com)
 /// @date    2023-05-06 10:28:53
 ///
 
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <fstream>
#include <iostream>
using std::cout;
using std::endl;
using std::set;
using std::map;
using std::vector;
using std::ifstream;
using std::string;
using std::istringstream;

class TextQuery
{
public:
	TextQuery()
	{	_file.reserve(100);	}

	void readFile(const string & filename);
	void query(const string & word);

private:
	void preprocessLine(string & line)
	{
		for(auto & ch : line) {
			if(!isalpha(ch)) {
				ch = ' ';	
			} else if(isupper(ch)) {
				ch = tolower(ch);
			}
		}
	}
private:
	map<string, int> _wordcnts;
	map<string, set<int>> _word2line;
	vector<string> _file;//完美hash,没有空间的浪费
};

void TextQuery::readFile(const string & filename)
{
	ifstream ifs(filename);
	if(!ifs) {
		cout << "ifstream open file " << filename << " error\n";
		return;
	}

	int cnt = 0;
	string line;
	while(getline(ifs, line)) {
		_file.push_back(line);//获取行号
		preprocessLine(line);
		string word;
		istringstream iss(line);
		while(iss >> word) {
			_word2line[word].insert(cnt);
			++_wordcnts[word];
		}
		++cnt;
	}
}
 
void TextQuery::query(const string & word)
{
	int times = _wordcnts[word];
	cout << word << " occurs " << times << 
		 (times > 1 ? " times" : " time") << endl;
	auto & lines = _word2line[word];
	for(auto & line : lines) {
		cout << "(line " << line + 1 << ") " << _file[line] << endl;
	}
}

void test0() 
{
	TextQuery tq;
	tq.readFile("china_daily.txt");
	string word;
	cout << "pls input a query word:" << endl;
	while(std::cin >> word) {
		tq.query(word);
	}
} 
 
int main(void)
{
	test0();
	return 0;
}








